#include "input_pipeline.h"

input_pipeline * input_pipeline_instance = NULL;

input_pipeline * input_pipeline::self(){
	if (!input_pipeline_instance)
		input_pipeline_instance = new input_pipeline;
	return input_pipeline_instance;
}

input_pipeline::input_pipeline (){
	if (load_settings()!=0){
		for (int i=0;i<512;i++)
			kb_SDL_map[i]=-1;
		for (int i=0;i<KB_LENGHT;i++)
			kb_map[i]=0;
		addkey(SDLK_ESCAPE,KB_ESCAPE);
		addkey(SDLK_w,KB_FORWARD);
		addkey(SDLK_a,KB_LEFT);
		addkey(SDLK_s,KB_BACKWARD);
		addkey(SDLK_d,KB_RIGHT);

		save_settings();
	}

	for (int i=0;i<KB_LENGHT;i++)
		kb_map_status[i]=0;

	mouse_x=0;
	mouse_y=0;
}

void input_pipeline::addkey(unsigned char sdl_key,unsigned char kb_key){
	kb_SDL_map[sdl_key]=kb_key;
	kb_map[kb_key]=sdl_key;
}

void input_pipeline::update(){
/*	for (int i=0;i<KB_LENGHT;i++)
		printf("%d ",kb_map_status[i]);
	printf("\n");
*/
	
	for (int i=0;i<KB_LENGHT;i++)
		kb_map_status[i]&=~KB_STATUS_CHANGED;
	while( SDL_PollEvent( &event ) ){
		if( event.type == SDL_QUIT )
			kb_map_status[KB_QUIT] = KB_STATUS_PRESSED|KB_STATUS_CHANGED;

		if (event.type==SDL_KEYDOWN)
			if (kb_SDL_map[event.key.keysym.sym]!=-1 ){
//				printf("%s %d %d %d\n",__FILE__,__LINE__,event.key.keysym.sym,kb_SDL_map[event.key.keysym.sym]);
				kb_map_status[kb_SDL_map[event.key.keysym.sym]]=KB_STATUS_PRESSED|KB_STATUS_CHANGED;
			}
			
		if (event.type==SDL_KEYUP)
			if (kb_SDL_map[event.key.keysym.sym]!=0 )
				kb_map_status[kb_SDL_map[event.key.keysym.sym]]=KB_STATUS_CHANGED;
		
		if (event.type==SDL_MOUSEBUTTONDOWN)
			switch (event.button.button){
				case SDL_BUTTON_LEFT:
					kb_map_status[KB_M1]=KB_STATUS_PRESSED|KB_STATUS_CHANGED;
					break;
				case SDL_BUTTON_RIGHT:
					kb_map_status[KB_M2]=KB_STATUS_PRESSED|KB_STATUS_CHANGED;
					break;
				case SDL_BUTTON_MIDDLE:
					kb_map_status[KB_M3]=KB_STATUS_PRESSED|KB_STATUS_CHANGED;
					break;
			}
		if (event.type==SDL_MOUSEBUTTONUP)
			switch (event.button.button){
				case SDL_BUTTON_LEFT:
					kb_map_status[KB_M1]=KB_STATUS_CHANGED;
					break;
				case SDL_BUTTON_RIGHT:
					kb_map_status[KB_M2]=KB_STATUS_CHANGED;
					break;
				case SDL_BUTTON_MIDDLE:
					kb_map_status[KB_M3]=KB_STATUS_CHANGED;
					break;
			}
		if (event.type==SDL_MOUSEMOTION){
			mouse_x=(double)event.motion.x/(double)render_pipeline::self()->get_screen_width();
			mouse_y=1-(double)event.motion.y/(double)render_pipeline::self()->get_screen_height();
		}
	}
}

unsigned char input_pipeline::_kb(unsigned char kb_key_in){
	return kb_map_status[kb_key_in];
}

int input_pipeline::load_settings(){
	FILE *config = fopen("./config_keyboard","r");
	if (config==NULL)
		return -1;
	for (int i=0;i<512;i++)
		if (fscanf(config,"%d",&kb_SDL_map[i])==EOF)
			return -1;
	for (int i=0;i<KB_LENGHT;i++)
		if (fscanf(config,"%d",&kb_map[i])==EOF)
			return -1;
	return 0;
}

int input_pipeline::save_settings(){
	FILE *config = fopen("./config_keyboard","w");
	if (config==NULL)
		return -1;
	for (int i=0;i<512;i++)
		fprintf(config,"%d \n",kb_SDL_map[i]);
	for (int i=0;i<KB_LENGHT;i++)
		fprintf(config,"%d \n",kb_map[i]);
	return 0;
}

double input_pipeline::_kb_mouse_wx(){
	return camera_x+2*camera_obzor*((mouse_x-0.5)*sin(camera_rot)+(mouse_y-0.5)*cos(camera_rot));
}

double input_pipeline::_kb_mouse_wy(){
	return camera_y+2*camera_obzor*(-(mouse_x-0.5)*cos(camera_rot)+(mouse_y-0.5)*sin(camera_rot));
}
